package org.lboot.rbac.controller;

import cn.dev33.satoken.stp.StpUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.lboot.core.auth.anno.CheckRole;
import org.lboot.core.domain.ErrMsg;
import org.lboot.core.domain.ResponseDTO;
import org.lboot.core.exception.BusinessException;
import org.lboot.llog.anno.ApiLog;
import org.lboot.rbac.module.role.SysRole;
import org.lboot.rbac.module.role.SysRoleService;
import org.lboot.rbac.module.user.SysUser;
import org.lboot.rbac.module.user.SysUserService;
import org.lboot.rbac.module.user.map.SysUserRole;
import org.lboot.rbac.module.user.map.SysUserRoleService;
import org.lboot.rbac.params.NewGrantParams;
import org.lboot.starter.plugin.rsr.RsrTree;
import org.springframework.http.HttpStatus;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Optional;

/**
 * @author kindear
 * 授权管理控制器
 */
@Slf4j
@RestController
@RequestMapping("system")
@AllArgsConstructor
@Api(tags = "授权管理")
@RsrTree("系统管理")
public class GrantController {
    SysUserService userService;

    SysRoleService roleService;

    SysUserRoleService userRoleService;
    @ApiLog("RBAC")
    @ApiOperation(value = "角色授权")
    @PostMapping("privilege/grant")
    @CheckRole(orPerm = "rbac:privilege:grant")
    public ResponseDTO<Object> doGrant(@Validated @RequestBody NewGrantParams params){
        // 判断用户是否存在
        Long roleId = params.getRoleId();
        Optional<SysRole> roleOp = roleService.getOne(roleId);
        if (!roleOp.isPresent()) throw new BusinessException(HttpStatus.NOT_FOUND, ErrMsg.build("未找到对应角色"));
        // 管理员拦截
        SysRole role = roleOp.get();
        if (role.getRoleKey().equals("admin")){
            if (!StpUtil.hasRole("admin")){
                return ResponseDTO.wrap(HttpStatus.FORBIDDEN,"无权操作角色【admin】");
            }
        }
        Long userId = params.getUserId();
        Optional<SysUser> userOp = userService.getOne(userId);
        if (!userOp.isPresent()) throw new BusinessException(HttpStatus.NOT_FOUND,ErrMsg.build("未找到对应用户"));
        // 判断是否存在相同授权
        if (userRoleService.isExistMap(userId,roleId)){
            throw new BusinessException(HttpStatus.BAD_REQUEST,ErrMsg.build("重复授权"));
        }
        SysUserRole userRole = new SysUserRole();
        userRole.setUserId(userId);
        userRole.setRoleId(roleId);
        return ResponseDTO.succData(
                userRoleService.saveOne(userRole)
        );
    }

    @ApiLog("RBAC")
    @ApiOperation(value = "取消授权")
    @PostMapping("privilege/cancel")
    @CheckRole(orPerm = "rbac:privilege:cancel")
    public ResponseDTO<Object> doCancel(@Validated @RequestBody NewGrantParams params){
        Long roleId = params.getRoleId();

        Long userId = params.getUserId();

        Optional<SysUserRole> grantMapOp = userRoleService.getMap(userId,roleId);

        if (!grantMapOp.isPresent()) throw new BusinessException(HttpStatus.NOT_FOUND,"授权不存在");

        SysUserRole grantMap = grantMapOp.get();

        Optional<SysRole> roleOp = roleService.getOne(roleId);

        // 管理员拦截
        if (roleOp.isPresent() ){
            SysRole role = roleOp.get();
            if (role.getRoleKey().equals("admin")){
                if (!StpUtil.hasRole("admin")){
                    return ResponseDTO.wrap(HttpStatus.FORBIDDEN,"无权操作角色【admin】");
                }
            }
        }
        userRoleService.deleteOne(grantMap.getId());

        return ResponseDTO.succMsg("取消成功");

    }

//    @Deprecated
//    @ApiLog
//    @PostMapping("privilege/grant")
//    @ApiOperation(value = "批量授权",notes = "覆盖(方法已弃用)")
//    @CheckRole(orPerm = "system:privilege:grant")
//    public ResponseDTO<Object> grantBatch(@RequestBody @Validated GrantParams params){
//        // 批量获取用户
//        List<Long> userIds = params.getUserIds();
//        //批量获取角色
//        List<Long> roleIds = params.getRoleIds();
//        // 清理
//        userRoleService.deleteByRoleIds(roleIds);
//        userRoleService.deleteByUserIds(userIds);
//        // 重新构建
//        Set<SysUserRole> maps = new HashSet<>();
//        for (int i=0;i<userIds.size();i++){
//            for (int j=0;j<roleIds.size();j++){
//                SysUserRole map = new SysUserRole();
//                map.setUserId(userIds.get(i));
//                map.setRoleId(roleIds.get(j));
//                maps.add(map);
//            }
//        }
//        // 存储
//        userRoleService.batchSave(maps);
//        return ResponseDTO.succMsg("成功");
//
//    }

//    @ApiLog
//    @PostMapping("/privilege/cancel")
//    @ApiOperation(value = "取消授权",notes = "")
//    @CheckRole(orPerm = "rbac:privilege:cancel")
//    public ResponseDTO<Object> cancelBatch(@RequestBody @Validated GrantParams params){
//        // 批量获取用户
//        List<Long> userIds = params.getUserIds();
//        List<SysUser> users = userService.getByIdBatch(userIds);
//        //批量获取角色
//        List<Long> roleIds = params.getRoleIds();
//
//        List<SysRole> roles = roleService.batchGet(roleIds);
//        //遍历更新用户(移除)
//        users = users.stream().peek(ele->{
//            roles.forEach(ele.getRoles()::remove);
//        }).collect(Collectors.toList());
//        return ResponseDTO.succData(
//                userService.batchUpdate(users)
//        );
//    }
}
